#include "spl.includes.h"
#include "splib.h"

using namespace SPLib;
using namespace SPLib::Windows;
using namespace SPLib::Geom;

FrameWnd::DropTarget::DropTarget(FrameWnd *wnd) : m_lRefCount(1), wnd(wnd)
{
  this->wnd = wnd;
}

ULONG FrameWnd::DropTarget::AddRef()
{
  return InterlockedIncrement(&m_lRefCount);
}

ULONG FrameWnd::DropTarget::Release()
{
  LONG count = InterlockedDecrement(&m_lRefCount);

  if (count)
    return count;

  delete this;
  return 0;
}

HRESULT FrameWnd::DropTarget::QueryInterface(REFIID iid, void **ppvObjectOut)
{
  if (iid == IID_IDropTarget || iid == IID_IUnknown)
  {
    AddRef();
    *ppvObjectOut = this;
    return S_OK;
  }
  else
  {
    *ppvObjectOut = 0;
    return E_NOINTERFACE;
  }
}

DWORD FrameWnd::DropTarget::DropEffect(DWORD grfKeyState, POINTL pt,
  DWORD dwAllowed)
{
  DWORD dwEffect = DROPEFFECT_NONE;

  if (grfKeyState & MK_CONTROL)
    dwEffect = dwAllowed & DROPEFFECT_COPY;
  else if (grfKeyState & MK_SHIFT)
    dwEffect = dwAllowed & DROPEFFECT_MOVE;

  if (!dwEffect)
  {
    if (dwAllowed & DROPEFFECT_COPY)
      dwEffect = DROPEFFECT_COPY;
    else if (dwAllowed & DROPEFFECT_MOVE)
      dwEffect = DROPEFFECT_MOVE;
  }

  return dwEffect;
}

HRESULT FrameWnd::DropTarget::DragEnter(IDataObject *pDataObject,
  DWORD grfKeyState, POINTL pt, DWORD *pdwEffectOut)
{
  Event::DragObjectEvent wEvent(pDataObject, grfKeyState, (PPOINT)&pt, pdwEffectOut);

  return wnd->onDragEnter(wEvent);
}

HRESULT FrameWnd::DropTarget::DragOver(DWORD grfKeyState, POINTL pt,
  DWORD *pdwEffectOut)
{
  Event::DragEvent wEvent(grfKeyState, (PPOINT)&pt, pdwEffectOut);

  return wnd->onDragOver(wEvent);
}

HRESULT FrameWnd::DropTarget::DragLeave()
{
  return wnd->onDragLeave();
}

HRESULT FrameWnd::DropTarget::Drop(IDataObject *pDataObject,
  DWORD grfKeyState, POINTL pt, DWORD *pdwEffectOut)
{
  Event::DragObjectEvent wEvent(pDataObject, grfKeyState, (PPOINT)&pt, pdwEffectOut);

  return wnd->onDrop(wEvent);
}